Skip to content

Native Animated - Support events using RCT{Direct|Bubbling}EventBlock on iOS#15611

Closed
janicduplessis wants to merge 2 commits into
react:masterfrom
janicduplessis:native-events-fix
Closed

Native Animated - Support events using RCT{Direct|Bubbling}EventBlock on iOS#15611
janicduplessis wants to merge 2 commits into
react:masterfrom
janicduplessis:native-events-fix

Conversation

@janicduplessis

@janicduplessis janicduplessis commented Aug 23, 2017

Copy link
Copy Markdown
Contributor

When calling a prop of type RCTDirectEventBlock or RCTBubblingEventBlock it uses a completely different code path than events using [RCTEventDispatcher sendEvent:] and those were not dispatched to the RCTEventDispatcherListeners. We also do some event name normalization which caused issues between the JS and native event names. To fix that I simply remove the parts we normalize from the event key.

Changelog:

[iOS] [Fixed] - Support events using RCT{Direct|Bubbling}EventBlock

Test plan:

Added a Slider (it used RCTBubblingEventBlock for it's onValueChange event) that can control a native animated value in RNTester to reproduce the bug and made sure this diff fixes it.

@facebook-github-bot facebook-github-bot added GH Review: review-needed CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. labels Aug 23, 2017
@pull-bot

pull-bot commented Aug 23, 2017

Copy link
Copy Markdown

@facebook-github-bot label Core Team

Attention: @janicduplessis, @shergin

Generated by 🚫 dangerJS

@shergin shergin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like two great PR mixed up here. 😄

Comment thread React/Base/RCTEventDispatcher.m Outdated
- (instancetype)initWithName:(NSString *)name viewTag:(NSNumber *)viewTag arguments:(NSArray *)arguments
{
self = [super init];
if (self) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One line, please.

Comment thread React/Base/RCTEventDispatcher.m Outdated
);
}

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate file, please.

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@shergin Updated

@nerdmed

nerdmed commented Aug 23, 2017

Copy link
Copy Markdown

@janicduplessis this is awesome! Looking forward for this!

@shergin

shergin commented Aug 23, 2017

Copy link
Copy Markdown
Contributor

@janicduplessis What does RCTInputEvent and Animated have in common?

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@shergin Ok I understand why you are confused :)

Not sure why it is called INPUT event because afaik it has nothing to do with inputs, I just kept the current naming.

So when using RCTDirectEventBlock to create a view manager prop it ends up here https://github.com/facebook/react-native/blob/master/React/Views/RCTComponentData.m#L242 then createEventSetter will create a block that calls into [sendInputEventWithName:] (https://github.com/facebook/react-native/blob/master/React/Views/RCTComponentData.m#L121) to dispatch the event to JS. We want to call the listeners there too like we do in [sendEvent:] so native animated can do its thing.

@janicduplessis

Copy link
Copy Markdown
Contributor Author

And the other part of the PR is to deal with the event name normalization that is done in sendInputEventWithName (https://github.com/facebook/react-native/blob/master/React/Base/RCTEventDispatcher.m#L91)

@shergin

shergin commented Aug 24, 2017

Copy link
Copy Markdown
Contributor

OMG, now I know how RCTDirectEvent works. Almost. Thanks!
I will try to figure it out. We have to split this anyways though.

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@shergin 👍 Let me know if you need more context on anything else.

@shergin

shergin commented Aug 25, 2017

Copy link
Copy Markdown
Contributor

@janicduplessis Could you please help me figure out why this was named sendInputEvent? Is it just because it was used for TextInput only?
Should we generalize this approach? And rename it?

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@shergin From doing a quick search looks like it is only used in createEventSetter and sendTextEventWithType. It has been deprecated for a while (https://github.com/facebook/react-native/blob/e1577df1fd70049ce7f288f91f6e2b18d512ff4d/React/Base/RCTEventDispatcher.h#L87) so changing / removing it should be fine.

There is also sendEvent which takes a RCTEvent and is similar to sendInputEvent but more complex, It uses an event queue and does optional coalescing. Ideally we'd always use sendEvent but I don't know if the scheduling would end up being exactly the same.

@shergin

shergin commented Aug 25, 2017

Copy link
Copy Markdown
Contributor

@janicduplessis I just want to know that we know what we are doing. And do the right things. 😄
I would love to adopt sendEvent... everywhere!

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@shergin Ok, I had a better look at that code and it should be possible to switch to using only sendEvent. There's a bit more overhead but it should not make a noticeable difference performance wise. Some of our more frequent events like onScroll already use sendEvent anyway.

I can put up a PR tomorrow to remove sendInputEvent and move everything to sendEvent.

@shergin

shergin commented Aug 25, 2017

Copy link
Copy Markdown
Contributor

@janicduplessis Great! Do you mean remove sendInputEvent from Animated of remove completely?

@janicduplessis

Copy link
Copy Markdown
Contributor Author

I think we can get rid of it completely and always use sendEvent

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@shergin Removed sendInputEvent and created a new RCTEvent class that can be used with sendEvent and that replicates the behaviour of sendInputEvent. Named it RCTComponentEvent since sendInputEvent was used to dispatch events to components (including but not limited to text input events). That name should make it a lot clearer what it is used for.

Also simplified dealing with non-coalescable events by automatically generating a coalescingKey is canCoalesce returns NO. Also made a few coalescing related methods/props optional so they can be omitted if canCoalesce is false. Otherwise every RCTEvent class would have to implement some unique key generator even if the event is never coalescable.

@janicduplessis

Copy link
Copy Markdown
Contributor Author

Also this should probably be split in 2 PRs, just wanted to keep it here for now but once we're happy with a solution I'll make a new PR for the removal of sendInputEvent.

@nerdmed

nerdmed commented Sep 29, 2017

Copy link
Copy Markdown

@janicduplessis @shergin any news here? What is needed to proceed with this pr?

Comment thread React/Base/RCTEventDispatcher.m Outdated
event.viewTag.intValue |
(((uint64_t)event.eventName.hash & 0xFFFF) << 32) |
(((uint64_t)event.coalescingKey) << 48)
(((uint64_t)([event canCoalesce] ? event.coalescingKey : RCTNonCoalescableEventKey++)) << 48)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We access optional canCoalesce and coalescingKey here.
So, we have two options here:

  1. Do responseToSelector check here.
  2. Make that props required for all implementations.

I strongly prefer 2 because we should maintain this function as perfromant as possible.

Right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no, I see, I am wrong.

@shergin

shergin commented Sep 30, 2017

Copy link
Copy Markdown
Contributor

@janicduplessis Okay, we will be back to this PR after landing of #15894. Right?

@janicduplessis

janicduplessis commented Sep 30, 2017

Copy link
Copy Markdown
Contributor Author

@shergin Yep, then I will rebase this PR on top of the event improvements

@facebook-github-bot

Copy link
Copy Markdown
Contributor

@janicduplessis I tried to find reviewers for this pull request and wanted to ping them to take another look. However, based on the blame information for the files in this pull request I couldn't find any reviewers. This sometimes happens when the files in the pull request are new or don't exist on master anymore. Is this pull request still relevant? If yes could you please rebase? In case you know who has context on this code feel free to mention them in a comment (one person is fine). Thanks for reading and hope you will continue contributing to the project.

@nerdmed

nerdmed commented Feb 2, 2018

Copy link
Copy Markdown

@janicduplessis thanks a lot for your previous effort on this PR. It would enable really nice native animations with RN. This become stale for more a couple of month now. Any change to get this going?

@pull-bot

pull-bot commented Apr 22, 2019

Copy link
Copy Markdown
Messages
📖 📋 Missing Summary - Can you add a Summary? To do so, add a "## Summary" section to your PR description. This is a good place to explain the motivation for making this change.

Generated by 🚫 dangerJS against 5967a1d75c7c6ee87ab93c8464d1550c3cad29b3

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@shergin Rebased and tested it still works :)

@react-native-bot react-native-bot added Includes Changelog Bug and removed Missing Changelog This PR appears to be missing a changelog, or they are incorrectly formatted. labels Apr 22, 2019
Comment thread Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m Outdated
@cpojer

cpojer commented Jun 4, 2019

Copy link
Copy Markdown
Contributor

What's the status of this PR?

@pull-bot

Copy link
Copy Markdown
Messages
📖 📋 Missing Summary - Can you add a Summary? To do so, add a "## Summary" section to your PR description. This is a good place to explain the motivation for making this change.

Generated by 🚫 dangerJS against 4fe14cf

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@cpojer @shergin Rebased this and made sure the fix is still needed and works.

@cpojer cpojer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's ship it.

@facebook-github-bot facebook-github-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cpojer is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@react-native-bot

Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @janicduplessis in 083f835.

When will my fix make it into a release? | Upcoming Releases

@react-native-bot react-native-bot added the Merged This PR has been merged. label Jun 19, 2019
@cpojer

cpojer commented Jun 19, 2019

Copy link
Copy Markdown
Contributor

Had to revert this because of:

react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m:35:11: error: no previous prototype for function 'RCTNormalizeAnimatedEventName' [-Werror,-Wmissing-prototypes]
NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
          ^

Could you send it again with this fixed?

@janicduplessis

Copy link
Copy Markdown
Contributor Author

@cpojer Fixed #25317

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API: Animated Bug CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Platform: iOS iOS applications. Ran Commands One of our bots successfully processed a command.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants